=Боевая система=

Боевая система адаптирована под игру "Вереница миров". По правилам игры игрок должен бросать кубики за себя и за противника и прибавлять значения к текущим значениям ЛОВКОСТЕЙ. Если значение противника больше - игроку наносится ущерб 2 очка (вычитается из СИЛЫ), если значение игрока больше значения противника, вычитаются из текущих параметров противника 2 очка.

Воспользоваться бластером можно в любой момент боя (если только пользоваться им не запрещено). Бластер мгновенно убивает противника независимо от уровня СИЛЫ и ЛОВКОСТИ.

Так же в некоторых случаях в игре "Вереница миров" используются различные бонусы и штрафы (их немного), в одном из случаев - прерывание боя с возможным продолжением, в паре случаев есть возможность сбежать или отказаться от боя.

Всё это нашло отражение в боевом механизме движка.

Сам боевой механизм представляет собой некоторый набор локаций и возможных динамических конструкций, а так же базу противников, вызываемых по меренеобходимости.

--Противники--

Противники - это особые объекты игры, принадлежащие классу <ratch>. Их описание, помимо имени, содержит некоторые данные, необходимые для реализации сражения. Вот список тегов, используемых в телах противников:

	[:short_word:]	-	короткое слово. Идентификатор вида/подвида противника. В игре "вереница миров", по причине использования упрощённой базы, каждому отдельному противнику соответствует отдельный идентификатор вида.

	[name:Имя|Имени|Имени|Имя|Именем|Имени:name]	-	падежные формы имени противника.

	[sex: :sex]	-	между тегами помещается значение 'male' или 'female', что соответствуют мужскому и женскому полу. Это значение необходимо для вывода надписей во время боя.

	[power:00]	-	одиночный тег. Начальная СИЛА противника

	[fast:00]	-	одиночный тег. Начальная ЛОВКОСТЬ противника

	[blow:00]	-	одиночный тег. Ущерб от удара противника. Если тег не указан, ущерб принимается равным 2.

Таким образом каждый отдельный противник изначально описывается в базе 'base.ratch'. Когда этот противник становится необходим (т.е. игрок приходит на локацию боя с этим противником), при использовании базы в игре создаётся объект класса <ratch>. Создание противника происходит тем же способом, что и любого другого объекта игры, но с обязательным указанием тега класса:

	gosub 'crt.obj','противник','','<ratch>'

Данная строчка означает, что на текущей локации будет создан противник, идентификатор вида которого соответствует слову 'противник'.

--Локация боя--

Даже если на локации будет создан противник, бой не начнётся, если локация не является локацией боя. Чтобы определить локацию, как локацию боя, необходимо в заголовке указать метку '<avs-enemy>'. Пример:

	$lvar['заголовок']='385<avs-enemy>'

Тогда при переходе на эту локацию и при выполнении кода на локации 'onNewLoc' к описанию локации добавится сыылка-приглашение начать битву:

	<avs-enemy><br><br><br><center><a href="exec:gosub ''int.war''" title="вызов обработчика боя" class="plain"><font size=+1>Сражаться</font></a></center></avs-enemy>

При нажатии на ссылку произойдёт обращение к локации, инициализирующей сражение, 'int.war'.

Первое обращение к этой локации характеризуется тем, что массив '$GAME_WAR[]' ещё пуст, в том числе и значение переменной $GAME_WAR['thiswar.'+$curloc]. По этому условию происходит инициализация и заполнение всех необходимых переменных:

	1. Обращаемся к текущей локации, чтобы вернуть значения $lvar и прочие.
	2. Запоминаем исходники.
		$GAME_WAR['заголовок.'+$curloc]=$lvar['заголовок']
		$GAME_WAR['исходник.'+$curloc]=$lvar['исходник']
		$GAME_WAR['exit.'+$curloc]=$lvar['exit']
		$GAME_WAR['DIN.'+$curloc]=$lvar['динамический код']
	3. Переключаем состояние боя в режим 'war'.
		$GAME_WAR['thiswar.'+$curloc]='war'
	4. Получаем штрафы и бонусы герою (только на время боя)
		GAME_WAR['hero.fast']=lvar['штраф.ловк']
	5. Уничтожаем $lvar
	6. Далее получаем список противников и инициализируем все необходимые для боя параметры:
		...
		GAME_WAR['ratch.power.'+$temp_id[0]]=func('get.tag.num',$args['ratch.body'],'power')
		GAME_WAR['ratch.power.max.'+$temp_id[0]]=GAME_WAR['ratch.power.'+$temp_id[0]]
		GAME_WAR['ratch.fast.'+$temp_id[0]]=func('get.tag.num',$args['ratch.body'],'fast')
		GAME_WAR['ratch.fast.max.'+$temp_id[0]]
		args['blow']=func('get.tag.num',$args['ratch.body'],'blow')
		if args['blow']=0: args['blow']=2
		GAME_WAR['ratch.blow.'+$temp_id[0]]=args['blow']
		...

		Как видно из этого кусочка кода, временные параметры противника строго привязаны к его уникальному идентификатору (здесь этот идентификатор выражен через $temp_id[0]). Далее различать разных противников движку помогает именно уникальный идентификатор.
	7. Теперь, когда все необходимые данные получены, инициализатор боя обращается к интерпретатору экрана боя - локации 'int.war.screen'. Эта локация генерирует конечный вид выводимой на экран информации из исходников, логов и прочих данных и представляет непосредственно на экран, используя 'int.screen'
	8. Таким образом помимо описания локации на экран выводится полный лог боя и таблица управления боем, где в виде гиперссылок указаны возможные действия над каждым отдельным противником.

Итак игроку предоставляется на выбор два действия в виде ссылок: "Атаковать" и "Застрелить из бластера". Рассмотрим, как происходит каждое действие. 

-Застрелить из бластера-

При выборе этого действия происходит обращение к локации 'int.war.blaster'. Здесь действует такой алгоритм:

	1. Проверяется бластер на наличие заряда. Если заряда нет - значит что-то в движке спрограммировано криво, ибо действие "застрелить из бластера" недоступно, если бластер разряжен. Если заряд есть, выполняются следующие пункты.
	2. В лог боя передаётся номер раунда.
	3. С бластера снимается один заряд
	4. СИЛА противника обнуляется. Фиксируется сообщение о его смерти.
	5. Количество убитых противников увеличивается на 1
	6. Если убит выделенный противник, с него снимается выделение.
	7. В лог боя добавляется сообщение о смерти противника.
	8. Выставляется номер нового раунда
	9. Проверяется, все ли противники мертвы (локация 'int.war.prv'. Здесь выставляется режим боя 'lose' или 'victory' в зависимости от поражения или победы.)
	10. Вновь обращаемся к локации 'int.war'.

-Атаковать-

При выборе этого действия происходит обращение к локации 'int.war.attack'. Здесь действует такой алгоритм:

	1. Противник, против которого применяется атака, выделяется. По правилам "Вереницы миров" нужно выбрать противника и сражаться с ним, пока не победишь. Потом выбрать следующего. Для этого и предназначено выделение - атаковать невыделенных противников нельзя. Но можно застрелить их из бластера.
	2. В лог боя передаётся номер раунда
	3. Производится бросок кубиков за игрока и определяются параметры удара героя.
	4. За каждого противника производится бросок кубиков и определяются параметры удара. Параметры удара противника сравниваются с параметрами удара игрока и производятся расчёты согласно правилам боя игры:
		a/ Если удар наносится герою, уменьшается сила героя через обращение к локации 'power' с передачей параметра 'war'.
		b/ Если удар наносится выделенному врагу, уменьшается текущая сила врага. Если при этом сила врага упала до нуля или ниже, фиксируется сообщение о его смерти, количество убитых противников увеличивается на 1, снимается выделение, в лог боя вносится сообщение о смерти противника.
		с/ если равны мощности ударов противника и героя, в лог боя добавляется сообщение о равенстве сил.
	5. Проверяется, все ли противники мертвы, и не мертвы ли вы (локация 'int.war.prv'. Здесь выставляется режим боя 'lose' или 'victory' в зависимости от поражения или победы.)
	6. Выставляется номер нового раунда.
	7. Вновь обращаемся к локации 'int.war'.

--Дополнительные параметры боя--

Эти данные заполняются на локации боя:

$lvar['exit'] - обязательная переменная для всех локаций боя. Здесь хранится название локации, на которую откроется переход в случае победы над противниками.

lvar['штраф.ловк'] - необязательная переменная. Штраф (отрицательное значение) или бонус (положительное значение) к ЛОВКОСТИ героя.

$lvar['динамический код'] - необязательная переменная. Сюда вносится динамический код, который нужно выполнять во время боя. Так, например, реализованы случаи, когда необходима победа до того, когда у противника иссякнет здоровье. Динамическому коду передаются следующие параметры:

	!war.round! - код выполняется перед началом нового раунда. Так реализован в "Веренице миров" бой, который нужно завершить за четыре раунда, см. 'page.185'.

	!war.refresh! - код выполняется всякий раз при обновлении экрана. Так реализован в "Веренице миров" бой, в котором нужно использовать очки ночного видения, см. 'page.121'.

	!war.powerdown! - код выполняется всякий раз, когда снижается здоровье героя. Так реализованы случаи предпоражения, когда противник должен прервать бой, когда здоровье героя достигло двух, см. 'page.153'.

	!war.ratchdown! - код выполняется всякий раз, когда снижается здоровье противника. Так реализованы случаи предвыигрыша, когда бой должен прекратиться до того, как противник умрёт, см. 'page.153'.

<non-blaster> - наличие этой метки в заголовке локации запретит игроку использовать бластер. Действие не появится.